package dgt;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;


public class KmlBuilder {
	private final SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();

	private final Pattern elementsPattern;
	private final Pattern fieldsPattern;
	
	public KmlBuilder(){
		elementsPattern = Pattern.compile("\\{(.*?)\\}");
		fieldsPattern = Pattern.compile("\"(.*?)\":(?:\"(.*?)\"|([\\d\\.-]+))");
	}
	
	public void buildKml(CharSequence data, OutputStream output, Charset charset) throws TransformerConfigurationException, SAXException{
		
		TransformerHandler th = initTransformerHandler(output, charset);
		th.startDocument();
		AttributesImpl atts = new AttributesImpl();
		atts.addAttribute("", "", "xmlns", "CDATA", "http://www.opengis.net/kml/2.2");
		th.startElement("", "", "kml", atts);
		th.startElement("", "", "Document", null);
		
		Matcher m = elementsPattern.matcher(data);
		while(m.find()){
			createPlaceMark(th, m.group(1));
		}
		
		th.endElement("", "", "Document");
		th.endElement("", "", "kml");
		th.endDocument();
	}
	
	private void createPlaceMark(TransformerHandler th, String element) throws SAXException {
		Matcher m = fieldsPattern.matcher(element);
		ElementHelper helper = new ElementHelper();
		while(m.find()){
			if(m.group(2) != null)
				helper.handleKeyValue(m.group(1), m.group(2));
			else
				helper.handleKeyValue(m.group(1), m.group(3));
		}
		th.startElement("", "", "Placemark", null);
		
		th.startElement("", "", "name", null);
		String aux = helper.generateName();
		th.characters(aux.toCharArray(), 0, aux.length());
		th.endElement("", "", "name");
		
		th.startElement("", "", "Point", null);
		th.startElement("", "", "coordinates", null);
		aux = helper.generateCoords();
		th.characters(aux.toCharArray(), 0, aux.length());
		th.endElement("", "", "coordinates");
		th.endElement("", "", "Point");
		
		th.endElement("", "", "Placemark");
	}

	private TransformerHandler initTransformerHandler(OutputStream output, Charset charset) throws TransformerConfigurationException{
		TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
		Transformer transformer = transformerHandler.getTransformer();
		transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
		transformer.setOutputProperty(OutputKeys.INDENT,"yes");
		
		StreamResult result = new StreamResult(new OutputStreamWriter(output, charset));
		transformerHandler.setResult(result);
		
		return transformerHandler;
	}
}
